<template>
  <div>
    <!-- banner -->
    <div class="banner-container">
      <img :src="bannerUrl" alt="" />
      <div class="banner-text">
        <div class="banner-text-title">辩论擂台</div>
        <div class="banner-text-desc">谁才是最强AI，吵一嘴就知道。</div>
      </div>
    </div>

    <!-- 主界面 -->
    <div v-if="debateRound === 0" class="debate-arena-container">
      <!-- 左模型 -->
      <div class="model-container left-model-container">
        <div class="model-background">
          <img src="~/assets/debateArena/kongzi_background.png" alt="" />
        </div>
        <div
          v-if="!selectLeftModel"
          class="add-model-btn"
          @click="selectLeftModel = true"
        >
          <PlusCircleFilled />
          <div class="add-model-text">添加模型</div>
        </div>
        <div v-else class="model-select-container">
          <div class="model-title">
            选择模型
            <div class="close-btn" @click="handleCloseSelect('left')">
              <CloseOutlined />
            </div>
          </div>
          <div class="model-grid-container">
            <div
              v-for="char in characterList"
              :key="char.id"
              class="model-item"
              :class="{
                'model-item-selected': leftModel && leftModel.id === char.id,
              }"
              @click="handleModelClick(char, 'left')"
            >
              <div class="model-item-icon">
                <img :src="char.avatar" alt="" />
              </div>
              <div class="model-item-title">{{ char.name }}</div>
            </div>
          </div>
        </div>
      </div>
      <!-- 右模型 -->
      <div class="model-container right-model-container">
        <div class="model-background">
          <img src="~/assets/debateArena/bolatu_background.png" alt="" />
        </div>
        <div
          v-if="!selectRightModel"
          class="add-model-btn"
          @click="selectRightModel = true"
        >
          <PlusCircleFilled />
          <div class="add-model-text">添加模型</div>
        </div>
        <div v-else class="model-select-container">
          <div class="model-title">
            选择模型
            <div class="close-btn" @click="handleCloseSelect('right')">
              <CloseOutlined />
            </div>
          </div>
          <div class="model-grid-container">
            <div
              v-for="char in characterList"
              :key="char.id"
              class="model-item"
              :class="{
                'model-item-selected': rightModel && rightModel.id === char.id,
              }"
              @click="handleModelClick(char, 'right')"
            >
              <div class="model-item-icon">
                <img :src="char.avatar" alt="" />
              </div>
              <div class="model-item-title">{{ char.name }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div v-else class="debate-round-container">
      <div
        v-for="message in chatHistory"
        :key="message.id"
        class="ai-message-container"
      >
        <div class="ai-message-avatar">
          <img
            :src="
              leftModel.name == message.name
                ? leftModel.avatar
                : rightModel.avatar
            "
            alt=""
          />
        </div>
        <div class="ai-message-wrapper">
          <div class="ai-message-name">{{ message.name }}</div>
          <div class="ai-message-content" :style="{'background-color': message.name != leftModel.name ? '#fff9fa' : '#f4f7ff'}">
            <template v-if="!message.content">
              <LoadingOutlined />
            </template>
            <template v-else>
              {{ message.content }}
            </template>
          </div>
        </div>
      </div>
    </div>

    <!-- 输入框 -->
    <div class="user-input-container">
      <a-textarea
        v-model:value="userInput"
        placeholder="请输入"
        :autoSize="{ minRows: 1, maxRows: 6 }"
        :maxlength="1000"
        @keydown="handleKeyDown"
      />
      <div class="tools-bar-wrapper">
        <div class="prompt-round">
          对比轮数
          <a-input-number v-model:value="round" :min="1" :max="8" />
        </div>
        <a-tooltip title="开始对比">
          <a-button
            type="primary"
            shape="circle"
            :icon="h(ArrowUpOutlined)"
            :loading="sendBtnLoading"
            @click="handleSendMessage"
          ></a-button>
        </a-tooltip>
      </div>
    </div>
  </div>
</template>

<script setup>
// ------------------- import -------------------
import { reactive, ref, onMounted, computed } from "vue";
import {
  PlusCircleFilled,
  ArrowUpOutlined,
  CloseOutlined,
  LoadingOutlined,
} from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import { getCharacters, contextChat } from "~/api/chat";

// banner图
const bannerUrl =
  "https://seven-cow.obs.cn-south-1.myhuaweicloud.com/banner/debate_arena_banner.png";

// ------------------- data -------------------
const characterList = reactive([]);

const prompt = ref("");
const round = ref(5);
const selectLeftModel = ref(false);
const selectRightModel = ref(false);
const leftModel = ref(null);
const rightModel = ref(null);
const userInput = ref("");
const sendBtnLoading = ref(false);
const chatHistory = reactive([]);
const debateRound = ref(0);
const isStreaming = ref(false); // 添加流式输出状态标志
// ------------------- function -------------------
// 初始化
const handleInit = async () => {
  await handleGetCharacters();
};

// 关闭选择模型
const handleCloseSelect = (type) => {
  if (type === "left") {
    selectLeftModel.value = false;
    leftModel.value = null;
  } else if (type === "right") {
    selectRightModel.value = false;
    rightModel.value = null;
  }
};

// 获取所有模型
const handleGetCharacters = async () => {
  const res = await getCharacters();
  characterList.push(...res.data);
};

// 处理模型卡片点击
const handleModelClick = (model, type) => {
  if (type === "left" && leftModel.value && leftModel.value.id === model.id) {
    // 如果点击已选中的模型，则取消选中
    leftModel.value = null;
  } else if (
    type === "right" &&
    rightModel.value &&
    rightModel.value.id === model.id
  ) {
    // 如果点击已选中的模型，则取消选中
    rightModel.value = null;
  } else {
    // 否则选中该模型
    if (type === "left") {
      leftModel.value = model;
    } else if (type === "right") {
      rightModel.value = model;
    }
  }
};

// 发送消息
const handleSendMessage = async () => {
  // 校验模型是否选中
  if (leftModel.value === null || rightModel.value === null) {
    message.error("请选择好两边的大模型");
    return;
  }
  if (userInput.value === "") {
    message.error("请输入对比主题");
    return;
  }
  if (round.value < 1 || round.value > 8) {
    message.error("对比轮数必须在1-8之间");
    return;
  }
  // 校验模型是否相同
  if (leftModel.value.id === rightModel.value.id) {
    message.error("请选择不同的大模型");
    return;
  }
  let prompt = userInput.value;
  userInput.value = "";
  debateRound.value += 1;
  // 开始聊天
  for (let i = 0; i <= round.value; i++) {
    // 确定当前轮次是哪个模型发言
    const currentModel = i % 2 === 0 ? leftModel.value : rightModel.value;
    const opponentModel = i % 2 === 0 ? rightModel.value : leftModel.value;

    // 添加当前发言的模型到聊天历史
    chatHistory.push({
      name: currentModel.name,
      content: "",
    });

    let message = "";
    if (i === 0) {
      message = `现在由你开始发言，主题是${prompt}`;
    } else {
      message = `根据对方辩手的观点，请合理辩论，主题是${prompt}`;
    }

    let system_prompt = `现在有一场辩论赛，你是${currentModel.name}，你的对手是${opponentModel.name}。你需要按照${currentModel.name}的角度发言，尽可能不说文言文，不能说与主题无关的内容`;

    // 构建聊天记录列表，role根据发言轮次动态变化
    let chatRecordList = chatHistory.map((item, index) => {
      // 确定每条记录的role
      // 对于偶数轮次（0,2,4...），偶数索引的记录是user，奇数索引是assistant
      // 对于奇数轮次（1,3,5...），偶数索引的记录是assistant，奇数索引是user
      const isEvenRound = i % 2 === 0;
      const isEvenIndex = index % 2 === 0;
      const role = isEvenRound
        ? isEvenIndex
          ? "user"
          : "assistant"
        : isEvenIndex
        ? "assistant"
        : "user";

      return {
        role: role,
        content: item.content,
      };
    });

    let record = "";
    chatHistory.forEach((item) => {
      if (item.content) {
        record += item.name + ": " + item.content + "\n";
      }
    });

    const res = await contextChat({
      message: system_prompt + "，\n" + message + "以下是辩论记录：\n" + record,
      chatHistory: chatRecordList,
      system_prompt: system_prompt,
      model: "doubao-seed-1.6",
    });
    const content = res.data.response;

    // 如果上一次流式输出没有结束，等待它结束
    if (isStreaming.value) {
      // 等待流式输出结束
      await new Promise((resolve) => {
        const checkInterval = setInterval(() => {
          if (!isStreaming.value) {
            clearInterval(checkInterval);
            resolve();
          }
        }, 100);
      });
    }

    // 开始新的流式输出
    await handleStreamMessage(content);
  }
};

const handleStreamMessage = (content) => {
  return new Promise((resolve) => {
    isStreaming.value = true; // 开始流式输出
    const targetIndex = chatHistory.length - 1;
    if (targetIndex >= 0) {
      let currentIndex = 0;
      const interval = setInterval(() => {
        if (currentIndex < content.length) {
          // 每次添加一个字符
          chatHistory[targetIndex].content += content[currentIndex];
          currentIndex++;
        } else {
          // 内容输出完毕，清除定时器
          clearInterval(interval);
          isStreaming.value = false; // 流式输出结束
          resolve(); // Promise解决，表示流式输出完成
        }
      }, 50); // 每50毫秒输出一个字符，可以根据需要调整速度
    } else {
      isStreaming.value = false; // 流式输出结束
      resolve(); // 如果没有目标索引，直接解决Promise
    }
  });
};
// ------------------- onMounted -------------------
onMounted(() => {
  handleInit();
});
</script>

<style lang="scss">
html,
body {
  background-color: #fff;
}

.banner-container {
  width: 100%;
  height: 400px;

  img {
    width: 100%;
    object-fit: cover;
  }

  .banner-text {
    position: absolute;
    top: 20%;
    left: 200px;
    color: rgba(8, 13, 30, 0.95);
    font-size: 60px;
    font-weight: normal;
    line-height: 80px;
    display: flex;
    flex-direction: column;

    &-title {
      font-family: "OPPOSans", sans-serif;
    }

    &-desc {
      font-family: "OPPOSans", sans-serif;
      font-size: 40px;
      line-height: 60px;
      color: rgba(8, 13, 30, 0.7);
    }
  }
}

// 主界面
.debate-arena-container {
  $layout-height: 60px;
  width: 100%;
  padding: 0 180px;
  height: 600px;
  display: flex;
  gap: 20px;
}

// 主界面
.debate-round-container {
  $layout-height: 60px;
  width: 100%;
  padding: 0 180px;
  margin: 20px 0;
  height: 600px;
  overflow: scroll;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

// 对话项内容
.ai-message-container {
  display: flex;
  gap: 10px;

  .ai-message-wrapper {
    display: flex;
    flex-direction: column;
    gap: 5px;
  }

  // 对话项内容
  .ai-message-content {
    background-color: #d1e3ff;
    padding: 12px 16px;
    border-radius: 8px;
    font-size: 14px;
    line-height: 1.5em;
    min-height: 1.5em;
    // 文字分段
    white-space: pre-wrap;
    word-break: break-word;
    // 防止文字超出容器
    overflow-wrap: break-word;
  }

  .ai-message-name {
    font-size: 12px;
    color: #666;
  }

  // 对话项头像
  .ai-message-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }

  // 对话项语音
  .audio-wrapper {
    cursor: pointer;
    transition: all 0.3s ease;
    user-select: none;

    &:hover {
      opacity: 0.8;
    }

    .audio-img {
      width: 20px;
      height: 20px;
      color: #333;
      overflow: hidden;
      flex-shrink: 0;
      margin-right: 10px;
    }
  }
}

// 提示词界面
.prompt-container {
  width: 300px;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px;
  background-color: #fcfcff;

  .prompt-title {
    font-size: 20px;
    font-weight: bold;
  }

  .prompt-input {
    display: flex;
    height: 100%;
    .ant-input {
      max-height: 100%;
    }
    textarea {
      resize: none;
    }
  }

  .prompt-round {
    display: flex;
    align-items: center;
    gap: 10px;
    .ant-input-number {
      flex: 1;
    }
  }

  .prompt-btn {
    display: flex;
    width: 100%;
    justify-content: center;
    .ant-btn {
      width: 100%;
    }
  }
}

// 模型界面
.model-container {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 20px 0px;
  border-radius: 8px;
  position: relative;

  // 模型界面背景
  .model-background {
    position: absolute;
    width: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0.15;

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }

  // 添加模型按钮
  .add-model-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    font-size: 60px;
    cursor: pointer;
    transition: all 0.3s ease;
    color: #2029459e;
    z-index: 10;

    .add-model-text {
      font-size: 18px;
      font-weight: bold;
      color: rgba(8, 13, 30);
    }

    &:hover {
      color: #202945;
    }
  }
}

.left-model-container {
  background-color: #f9faff;
}

.right-model-container {
  background-color: #fff9fa;
  margin-right: 20px;
}

.model-select-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding: 20px;
  backdrop-filter: blur(10px);

  .model-title {
    font-size: 16px;
    font-weight: bold;
    color: #1a1a1a;
    margin-bottom: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .close-btn {
    color: #666;
    cursor: pointer;
    transition: all 0.3s ease;

    &:hover {
      opacity: 0.8;
    }
  }

  .model-grid-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    grid-gap: 10px;
    margin-bottom: 24px;
    height: 100%;
    overflow: auto;

    .model-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 10px;
      padding: 16px;
      border-radius: 10px;
      background-color: #fff;
      cursor: pointer;
      transition: all 0.3s ease;
      border: 1px solid #f0f0f0;

      &:hover {
        box-shadow: 0 8px 16px rgba(0, 0, 0, 0.02);
        border-color: #4096ff;
      }

      .model-item-icon {
        width: 60px;
        height: 60px;
        border-radius: 50%;
        overflow: hidden;
        background-color: #f5f5f5;
        display: flex;
        justify-content: center;
        align-items: center;

        img {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }
      }

      .model-item-title {
        font-size: 14px;
        font-weight: 500;
        color: #333;
        text-align: center;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      &.model-item-selected {
        border-color: #4096ff;
        background-color: #f5fbff;
      }
    }
  }

  .model-select-btn {
    display: flex;
    justify-content: center;
  }
}

// 用户输入框
.user-input-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  gap: 10px;
  padding: 10px;
  width: calc(100% - 380px);
  min-height: 100px;
  margin: 50px 180px;
  margin-top: auto;
  border: 1px solid #ddd;
  border-radius: 8px;
  background-color: #fff;
  box-shadow: 0 0 12px rgba(0, 0, 0, 0.04);
  transition: all 0.3s ease;
  z-index: 1000;
  position: relative;

  &::before {
    content: "";
    position: absolute;
    top: -51px;
    left: 0px;
    right: 0px;
    width: 100%;
    height: 50px;
    background: linear-gradient(to top, #fff 0%, #ffffff00 100%);
    z-index: 10;
    transition: all 0.3s ease;
  }

  &:hover {
    border: 1px solid #4096ff;
  }

  /* 当输入框聚焦时，修改父容器样式 */
  &:has(.ant-input:focus) {
    border: 1px solid #4096ff;
  }

  .ant-input {
    border: none;
    outline: none;
    resize: none;
    box-shadow: none;
    font-size: 14px;
    color: #333;
    background-color: transparent;
  }

  // 工具条
  .tools-bar-wrapper {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 0 10px;
    gap: 20px;

    .prompt-round {
      display: flex;
      align-items: center;
      gap: 10px;
      margin-right: 20px;
      color: #333;
      font-size: 14px;
      .ant-input-number {
        flex: 1;
      }
    }
  }
}
</style>
